//
//  SLLineChart.swift
//  SLLineChartDemo
//
//  Created by wsl on 16/7/2.
//  Copyright © 2016年 wsl. All rights reserved.
//

import UIKit
import pop

class SLLineChart: UIView {

    /// everry lineView width
    var lineWidth: CGFloat = 3
    /// text color
    var textColor: UIColor = UIColor.white
    /// bottomGridentColor and topGridentColor are decided lineView backgroundColor
    var bottomGridentColor: UIColor = UIColor.red
    var topGridentColor: UIColor = UIColor.orange
    
    fileprivate var yMaxValue: CGFloat = 100
    
    fileprivate let padding: CGFloat = 10
    
    fileprivate let labelHeight: CGFloat = 20
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        self.clipsToBounds = true
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    func storke(_ yValues: [Int], texts: [String]) {
        for view in self.subviews {
            view.removeFromSuperview()
        }
        var maxValue = 0;
        for value in yValues {
            if value > maxValue {
                maxValue = value
            }
        }
        yMaxValue = max(CGFloat(maxValue),1);
        drawLine(yValues)
        addText(texts)
    }
    
    fileprivate func drawLine(_ values :[Int]) {
        let margin = (frame.size.width - 2 * padding) / CGFloat(values.count) - lineWidth
        for (i,value) in values.enumerated() {
            let view = UIView.init()
            view.frame = CGRect(x: padding + CGFloat(i)*(lineWidth + margin), y: (frame.size.height - labelHeight) / 2, width: lineWidth, height: frame.size.height - labelHeight)
            view.backgroundColor = UIColor.clear
            addSubview(view)
            let shapeLayer = getShapeLayer(value, rect: CGRect(x: frame.origin.x, y: frame.origin.y + (frame.size.height - labelHeight) * CGFloat(1 - CGFloat(value) / yMaxValue), width: lineWidth, height: (frame.size.height - labelHeight) * CGFloat(CGFloat(value) / yMaxValue)), view: view)
            view.layer.addSublayer(shapeLayer)
            view.clipsToBounds = true
            view.layer.anchorPoint = CGPoint(x: 0.5, y: 1)
            animation(view.layer)
        }
    }
    
    fileprivate func addText(_ texts: [String]) {
        let margin = (frame.size.width - 2 * padding) / CGFloat(texts.count) - lineWidth
        for (i,text) in texts.enumerated() {
            let label = UILabel.init()
            label.center = CGPoint(x: padding + CGFloat(i)*(lineWidth + margin) + lineWidth / 2, y: frame.size.height - labelHeight / 2)
            label.bounds = CGRect(x: 0, y: 0, width: frame.size.width / CGFloat(texts.count), height: labelHeight)
            label.text = text
            label.textColor = textColor
            label.font = UIFont.systemFont(ofSize: 9.0)
            label.textAlignment = NSTextAlignment.center
            addSubview(label)
        }
    }
    
    let gradientLayer = CAGradientLayer()
    let shapeLayer = CAShapeLayer()
    fileprivate func getShapeLayer(_ value: Int, rect: CGRect, view: UIView) -> CAShapeLayer {
        let path = UIBezierPath.init()
        let controlA = CGPoint(x: rect.origin.x, y: rect.origin.y + rect.size.height)
        let controlB = CGPoint(x: rect.origin.x, y: rect.origin.y)
        let controlC = CGPoint(x: rect.origin.x + lineWidth, y: rect.origin.y)
        let controlD = CGPoint(x: rect.origin.x + lineWidth, y: rect.origin.y + rect.size.height)
        
        let leftA = CGPoint(x: controlA.x, y: controlA.y - lineWidth / 2)
        let rightA = CGPoint(x: controlA.x + lineWidth / 2, y: controlA.y)
        let leftB = CGPoint(x: controlB.x, y: controlB.y + lineWidth / 2)
        let rightB = CGPoint(x: controlB.x + lineWidth / 2, y: controlB.y)
        let leftC = CGPoint(x: controlC.x - lineWidth / 2, y: controlC.y)
        let rightC = CGPoint(x: controlC.x, y: controlC.y + lineWidth / 2)
        let leftD = CGPoint(x: controlD.x - lineWidth / 2, y: controlD.y)
        let rightD = CGPoint(x: controlD.x, y: controlD.y - lineWidth / 2)
        
        path.move(to: leftA)
        path.addLine(to: leftB)
        path.addQuadCurve(to: rightB, controlPoint: controlB)
        path.addLine(to: leftC)
        path.addQuadCurve(to: rightC, controlPoint: controlC)
        path.addLine(to: rightD)
        path.addQuadCurve(to: leftD, controlPoint: controlD)
        path.addLine(to: rightA)
        path.addQuadCurve(to: leftA, controlPoint: controlA)
        path.close()
        
        let gradientLayer = CAGradientLayer()
        gradientLayer.frame = rect
        gradientLayer.cornerRadius = lineWidth / 2
        gradientLayer.colors = [bottomGridentColor.cgColor, topGridentColor.cgColor]
        view.layer.addSublayer(gradientLayer)
        
        let shapeLayer = CAShapeLayer()
        shapeLayer.frame = rect
        shapeLayer.path = path.cgPath
        shapeLayer.fillColor = UIColor.clear.cgColor
        
        gradientLayer.mask = shapeLayer
        
        return shapeLayer
    }
    
    fileprivate func animation(_ layer: CALayer) {
        
        let popAnimation = POPSpringAnimation.init(propertyNamed: kPOPLayerSize)
        popAnimation?.fromValue = NSValue.init(cgSize: CGSize.zero)
        popAnimation?.toValue = NSValue.init(cgSize: CGSize(width: layer.bounds.size.width, height: layer.bounds.size.height))
        popAnimation?.springSpeed = 1.5
        popAnimation?.clampMode = 1
        layer.pop_add(popAnimation, forKey: "sizeAnimation")

    }
    
}
